בס ד מבני נתונים עצים שיעור 7 שי גולן כ ח בניסן, תשע ו 6 במאי 2016 תקציר בתרגול זה נתחיל לדון בעצים. נגדיר עצים כלליים ועצים בינאריים, ונציג את ההגדרות הבסיסיות בתחום. נתרגל הוכחת תכונות של עצים באמצעות אינדוקציה בכלל ואינדוקציה על מבנה העץ בפרט, ונראה אלגוריתמים רקורסיבים לזיהוי תכונות של עצים. בתחילת הקורס ראינו שני מבני נתונים פיזיים עיקריים מערך ורשימה מקושרת. המבנים האחרים(תור, רשימה, דו תור ועוד) היו מבנים לוגיים שמומשו באמצעות מערכים או רשימות. השיעור נלמד על עצים, שמוטיבציה עיקרית לשימוש בהם היא נסיון להרוויח הן מהיתרונות של מערכים והן מהיתרונות של רשימות מקושרות. ברשימה מקושרת, כל קודקוד מכיל ערך ומצביע אחד לקודוקוד הבא. ניתן להגדיר עץ כללי באופן זהה, פרט לכך שבמקום להכיל מצביע אחד לקודקוד הבא הוא מכיל קבוצה של מצביעים לאיברים אחרים. מבנה זה מאפשר באופן מיידי ליצג בצורה משמעותית נתונים שמתקיימת ביניהם היררכיה טבעית. למשל כתובות שמחולקות למדינה עיר רחוב מספר בית. מאמר שמחולק לפרקים תתי פרקים משפטים סעיפים. וכו. 1. ישראל (א) רמת גן i. מקס ואנה ווב.ii הרא ה (ב) תל אביב i. דיזינגוף.ii אלנבי 2. אנגליה (א) לונדון מבוסס על הסיכומים של ד ר גלעד אשרוב ומר אבישי ינאי. 1
i. רחוב בייקר א. בית 221B יש חלוקות בהן ההיררכיה בין הרמות טבעית, ואין הבדל מהותי בין הרמות. דוגמה שנתקלתם בה בהרצאה היא עצי ביטוי אריתמטי, בהם קודקודים באותה רמה מייצגים ביטויים המחושבים באותו שלב. דוגמה נוספת היא עצים משפחתיים, כאשר מסתכלים על כל הצאצאים של אדם מסוים. אלו המקרים בהם השימוש בעצים הוא הטבעי ביותר. הגדרה רקורסיבית לעצים כלליים היא: 1. קודקוד שורש. 2. קבוצת בנים, שכל בן הוא עץ בפני עצמו. אנו משתמשים במונחים מעולם הצומח(כמו שורש ועלה) ומעולם הגנאולוגיה(כמו בן, הורה/אב, אח, נכד וכו ). אנו נשתמש לרוב באות T לייצוג עץ, והמספר T = n יסמן את מספר הקודקודים בעץ. הגדרות בסיסיות בעצים: עומק של קודקוד עומק של קודקוד הוא מרחקו מהשורש(=אורך המסלול הקצר ביותר מהשורש אליו), כמובן שהעומק של השורש הוא 0. גובה העץ רמה עלה אורך המסלול הקצר ביותר משורש לקודקוד כלשהו כלומר העומק המקסימלי שקיים בעץ. מסומן לרוב בh הרמה הi של העץ היא קבוצת הקודקודים בעומק i בעץ. קודקוד ללא בנים. צומת פנימי קודקוד שאיננו עלה. ע מ לשמור קבוצת בנים של קודקוד, יש צורך במבנה שיהיה מסוגל לשמור קבוצה שכזו. אם גודל הקבוצה לא חסום, הדרך הפשוטה ביותר לאחסן את המידע הזה היא במעין רשימה מקושרת. ניתן לממש את הרשימה הזו בתוך המבנה של העץ כל קודקוד יכיל מצביע ל בן הראשון(בכור) (הבן השמאלי ביותר) ול אח הבא (אח ימני). בצורה כזו כדי להגיע מקודקוד אב לבן מסוים שלו, צריך לעבור בעזרת המצביע לבן הראשון, ולעבור על האחים עד שמגיעים לבן הדרוש. בצורה כזו כל קודקוד מכיל שני ולאח הימני(בצבע כחול באיור 1). מה שמביא אותנו באופן טבעי להגדרה של עצים בינאריים, שהם עצים בהם לכל קודקוד יש שני בנים. 1 עצים בינאריים עץ בינארי, דומה לעצים כללים, אך הוא מוגדר בצורה יותר מבנית. לכל קודקוד יש בן ימני ובן שמאלי, כך שגם אם יש לקודקוד מסוים בן אחד, יש משמעות לשאלה האם הוא מוגדר כבן הימני או כבן השמאלי. הגדרה רקורסיבית פורמלית: הגדרה 1 עץ בינארי הוא: 1. עץ ריק, או 2
איור 1: ייצוג עץ כללי באמצעות עץ בינארי בשיטת בן שמאלי אח ימני (מתוך ויקיפדיה) a a b b איור 2: שני עצים בינאריים שונים 2. שורש ושני תתי עצים בינאריים תת עץ ימני ותת עץ שמאלי. המבניות של העץ הבינארי מתבטאת למשל בדוגמה שבאיור 2, שבו ניתן לראות שני עצים בינאריים שונים, על אף ששניהם מורכבים מקודקוד שורש a עם בן אחד b. הגדרה 2 עץ בינארי שלם 1 עץ בינארי שכל עליו נמצאים באותה רמה(אם גובה העץ d, עומק כל עלה הוא בדיוק d). הגדרה 3 עץ בינארי מלא עץ בינארי בו כל קודקוד הוא עלה או שיש לו שני בנים. שאלה 4 מה מספר הקודקודים בעץ בינארי שלם? תשובה: בעץ בינארי שלם בגובה h מספר העלים הוא בדיוק 2, h ובאופן כללי מספר הקודקודים ברמה הi הוא 2. i לכן סה כ מספר הקודקודים בעץ בינארי שלם הוא: n = h 2 i = 2 h+1 1 i=0 לחילופין, בעץ בינארי שלם עם n קודקודים, גובה העץ הוא = 1 (1 + log(n h =.Θ(log n) 1 בהגדרה זו והבאה נעקוב אחר השמות כפי שהם מופיעים בספר של קורמן ועמיתיו, ישנם מקומות בהם עץ בינארי מלא ושלם מוגדרים בצורה הופכית. 3
איור 3: שני עצים בינאריים שונים בהמשך הלימוד נראה אלגוריתמים רבים(כמו חיפוש, הכנסה ומחיקה בעץ חיפוש בינארי) שזמן ריצתם הוא פונקציה של גובה העץ, ומכאן הייתרון לעצים שלמים שגובהם הוא.O(log n) שאלה 5 תן חסם לגובה של עץ בינארי מלא? מה היחס בין מספר העלים למספר הקודקודים הפנימיים בעץ בינארי מלא? תשובה: עץ עם n קודקודים גובהו יהיה לכל הפחות (n,log(n + (1 1 = Θ(log כאשר עץ בינארי (כמעט ( 2 שלם הוא העץ הנמוך ביותר האפשרי בהינתן n קודקודים. מהצד השני ניתן n 1 n+1 2 מהקודקודים מהווים שרוך ו 2 להראות עצים בינאריים שגובהם Θ(n) h = כך ש מהקודקודים הם עלים. ראו לדוגמא איור 3 עם = 9 n ו 4 = h. ניתן להראות שמספר הקודקודים הפנימיים בעץ בינארי מלא הוא מספר העלים פחות.1 טענה 6 בעץ בינארי מלא עם m עלים יש בדיוק 1 mקודקודים פנימיים. הוכחה: נוכיח באינדוקציה על m. עבור = 1 m, עץ מלא עם עלה 1 חייב להיות מורכב רק משורש. נ ימוק: יש בעץ עלה אחד, נניח בשלילה שגובה העץ הוא לפחות 1, אזי יש עלה בעומק המקסימלי של העץ. לעלה הזה חייב להיות אבא שהוא קודקוד פנימי(מכיוון שהעלה הוא לא השורש), ובגלל שזהו עץ בינארי מלא, לאבא הזה חייב להיות בן נוסף וגם הוא צריך להיות עלה(כי הוא בעומק המקסימלי בעץ) מכאן שיש שני עלים בסתירה להנחה. לכן בהכרח גובה העץ הוא 0, כלומר העץ מכיל עלה אחד ואפס קודקודים פנימיים.. נניח שהטענה נכונה עבור m, ונסתכל על עץ בינארי מלא T עם + 1 m עלים. נסתכל על עלה ברמה העמוקה ביותר של T. לעלה זה חייב להיות אבא v T שהוא קודקוד פנימי(כי גובה העץ 1 h), ולאבא הזה חייבים להיות שני בנים שהם עלים(כי הם ברמה העמוקה ביותר בעץ). נסתכל על העץ T המתקבל ממחיקת שני הבנים של v. בעץ זה יש בדיוק m) + (1 2 + 1 = m עלים, מכיוון שהוא התקבל ע י מחיקה של שני עלים ויצירה של עלה חדש( v ) מהעץ T. 2 עץ בינארי כמעט שלם הוא עץ המתקבל מעץ בינארי שלם ע י מחיקה של מספר כלשהו של עלים מהרמה העמוקה ביותר החל מהעלה השמאלי ביותר באופן רציף. 4
ע פ הנחת האינדוקציה יש ב T בדיוק 1 m קודקודים פנימיים, וכל אחד מהם הוא קודקוד פנימים גם ב T. ב T יש קודקוד פנימי אחד נוסף v. לכן סה כ יש ב T בדיוק m 1 + 1 = m קודקודים פנימיים. אפשרות אחרת היא להוכיח את צעד האינדוקציה באמצעות אינדוקציה על מבנה העץ. הוכחה: יהי עץ בעל + 1 m עלים. מכיוון שהעץ מלא, לשורש העץ יש שני בנים. נסמן את מספר העלים של תת העץ השמאלי ב m 1 ואת מספר העלים בתת העץ הימני ב m. 2 מתקיים m 1 m ולכן הנחת האינדוקציה חלה על תת העץ השמאלי, ובאופן זהה m 2 m והנחת האינדוקציה חלה גם על תת העץ הימני. לכן בתת העץ השמאלי יש m 1 1 קודקודים פנימיים, ובתת העץ הימני יש m 2 1 קודקודים פנימיים. השורש הוא קודקוד פנימי, ולכן בעץ כולו יש m 1 1 + m 2 1 + 1 קודקודים פנימיים. אך + 1 m m 1 + m 2 = ולכן מספר הקודקודים הפנימיים בעץ הוא בדיוק m. ישנם אלגוריתמים בהם המידע המיוצג נשמר רק בעלים, באלגוריתמים כאלה, שימוש בעצים מלאים מבטיח שהזכרון יהיה לינארי בגודל המידע. שאלה 7 מרחק בין צמתים בגרף (ובפרט, בעץ) הוא אורך המסלול הקצר ביותר. קוטר של גרף הוא המרחק המקסימלי בין זוג צמתים כלשהו בגרף. כלומר D = max d(u, v) u,v נעסוק בשאלת הקוטר של עץ בינארי. הוכח או הפרך: בהינתן עץ בינארי T עם קוטר D קיים מסלול באורך D העובר בשורש. הצע אלגוריתם למציאת קוטר הגרף לעצים. תשובה: הטענה לא נכונה. למשל העץ : איור 4: קוטר העץ =4 טענה מדויקת תהיה הגדרה רקורסיבית: בהינתן עץ T עם שני עצים מושרשים T L ו T R הקוטר של הגרף הוא המקסימום מבין: הקוטר של,T L הקוטר של T R והגובה של T +הגובה L של + T R.2 תרגום של הנוסחה לאלגוריתם: 5
נכתוב פונקציה רקורסיבית המחזירה את קוטר העץ וגובהו. הקוטר יחושב בדיוק לפי הנוסחה שנתנו, והגובה יחושב באמצעות המקסימום מבין גבהי העצים המושרשים + 2. הגובה והקוטר של עלה הם 0. הגובה והקוטר של עץ ריק יוגדרו כ 1 ע מ להתאים להגדרה הרקורסיבית ללא צורך בחלוקה למקרים שונים. 6